/// 列表（List）
void initList_01 () {
  /// 固定长度的列表，一旦定义就无法改变长度
  var fixedLengthList = List<int>(5);
  // -> [null, null, null, null, null]

  fixedLengthList[0] = 87;
  // -> [87, null, null, null, null]

  // fixedLengthList[0];
  // -> 87

  // 赋值超出长度会报错
  // fixedLengthList[8] = 32;
  // -> Uncaught Error: RangeError (index):
  // Index out of range: index should be less than 5: 8

  // 修改长度会报错
  // fixedLengthList.length = 0;
  // -> Uncaught Error: Unsupported operation: set length


  /// 可改变长度的列表，可以根据需要改变长度
  var growableList = <int>[1, 2];
  // -> [1, 2]

  growableList.length = 0;
  // -> []

  growableList.add(499);
  // -> [499]

  growableList[0] = 87;
  // -> [87]
}

/// 几种构造函数
// List([int length])
void initList_02 () {
  /// 创建固定长度的列表
  var fixedLengthList = List(3);
  // -> [null, null]

  // fixedLengthList.length
  // -> [3]

  /// 创建可改变长度的列表
  var growableListA = []; // List() == []
  // -> []

  // growableListA.length
  // -> 0

  growableListA.length = 3;
  // -> [3]

  /// 创建有初始长度并可改变长度的列表
  var growableListB = []..length = 500; // List()..length = 500
  // -> [null, null, ...500]

  // growableListB.length;
  // -> 500

  growableListB.length = 300;
  // -> 300

  growableListB.length = 400;
  // -> 400

  growableListB.length = 600;
  // -> 600


  /// List.unmodifiable(Iterable elements)
  // 创建包含所有元素的固定长度列表
  var fixedLengthListB = List.unmodifiable([1, 2, 3]);
  // -> [1, 2, 3]

  // fixedLengthListB.length;
  // -> 3

  // 报错，长度不可变
  // fixedLengthListB.length = 600;
  // -> Uncaught Error: Unsupported operation: set length

  /// List.from(Iterable elements, {bool growable: true})
  // 创建包含所有元素的可改变长度列表
  var growableListC = List.from([1, 2, 3]);

  // growableListC.length;
  // -> 3

  growableListC.add(4);
  // -> [1, 2, 3, 4]

  /// List.filled(int length, E fill, {bool growable: false})
  // 为所有元素统一赋值，固定长度，不能再添加元素
  List fixedLengthListD = List<int>.filled(3, 0);
  // -> [0, 0, 0]

  fixedLengthListD[2] = 10;
  // -> [0, 0, 10]

  // 报错
  // fixedLengthListD.add(4);
  // -> Uncaught Error: Unsupported operation: add

  /// List.generate(int length, E generator(int index), {bool growable: true})
  // 用生成器给所有元素赋初始值
  List fixedLengthListE = List<int>.generate(4, (int index) {
    return index * index;
  });
  // -> [0, 1, 4, 9]

  fixedLengthListE.add(4);
  // -> [0, 1, 4, 9, 4]
}

/// 所有属性
void initList_03 () {
  print('\x1B[102m  所有属性  \x1B[0m');
  var growableList = <int>[1, 2, 3, 4, 5];

  // 返回第一个元素
  print(growableList.first);
  // -> 1

  // 返回最后一个元素
  print(growableList.last);
  // -> 5

  // 返回列表的哈希码
  print(growableList.hashCode);
  // -> 950395819

  // 列表是否为空
  print(growableList.isEmpty);
  // -> false

  // 列表是否不为空
  print(growableList.isNotEmpty);
  // -> true

  // 返回一个新的迭代器
  print(growableList.iterator);
  // -> Instance of 'ArrayIterator<int>'

  // 列表中多少个元素
  print(growableList.length);
  // -> 5

  // 返回相反顺序的列表
  print(growableList.reversed);
  // -> (5, 4, 3, 2, 1)

  // 返回对象运行时的类型
  print(growableList.runtimeType);
  // -> List<int>

  // 列表是否只有一个元素，则否报错
  // print(growableList.single);
  // -> Uncaught Error: Bad state: Too many elements
}

/// 常用方法
void initList_04 () {
  print('\x1B[102m  常用方法  \x1B[0m');
  var growableList = List.from([1, 2, 3]);

  // 返回列表的字符串表示
  print(growableList.toString());
  // -> [1, 2, 3]

  // 返回列表的集表示
  print(growableList.toSet());
  // -> [1, 2, 3]

  // 返回列表的列表表示
  print(growableList.toList());
  // -> [1, 2, 3]

  // 用指定字符连接列表元素
  print(growableList.join(','));
  // -> 1,2,3
}

/// 给列表增加元素
void initList_05 () {
  print('\x1B[102m  给列表增加元素  \x1B[0m');
  // List growableList = new List();
  var growableList = [];

  // 增加一个元素到列表末尾
  growableList.add(10);
  print(growableList);
  // -> [10]

  // 增加一个元素到指定下标
  growableList.insert(1, 20);
  print(growableList);
  // -> [10, 20]

  // 增加一个列表到列表末尾
  growableList.addAll([30, 60]);
  print(growableList);
  // -> [10, 20, 30, 60]

  // 增加一个列表到指定下标
  growableList.insertAll(3, [40, 50]);
  print(growableList);
  // -> [10, 20, 30, 40, 50, 60]
}

/// 各种删除操作的方法
void initList_06 () {
  print('\x1B[102m  各种删除操作的方法  \x1B[0m');
  // List growableList = new List.from([1, 2, 3, 3, 3, 4]);
  var growableList = List.from([1, 2, 3, 3, 3, 4]);
  // -> [1, 2, 3, 3, 3, 4]

  // 移除列表中匹配的第一个元素
  growableList.remove(3);
  print(growableList);
  // -> [1, 2, 3, 3, 4]

  // 移除列表中第几个元素
  growableList.removeAt(0);
  print(growableList);
  // -> [2, 3, 3, 4]

  // 移除列表中最后一个元素
  growableList.removeLast();
  print(growableList);
  // -> [2, 3, 3]

  // 移除列表的所有元素
  growableList.clear();
  print(growableList);
  // -> []

  var listB = <int>[1, 2, 3, 4, 5];
  // 移除开始下标（不包括）至结束下标（包括）内的元素
  listB.removeRange(1, 4);
  print(listB);
  // -> [1, 5]

  var listA = <int>[1, 2, 3, 4, 5];
  // 移除并替换开始下标（不包括）至结束下标（包括）内的元素
  listA.replaceRange(1, 4, [6, 7]);
  print(listA);
  // -> [1, 6, 7, 5]

  var numbersA = <String>['one', 'two', 'three', 'four'];
  /*  移除所有满足条件的元素，此为Dart的一种速写语法
        numbersA.removeWhere((item) => item.length == 3);   */
  numbersA.removeWhere((item) {
    // 字符串的长度 == 3
    return item.length == 3;
  });
  print(numbersA);
  // -> [three, four]

  var numbersB = <String>['one', 'two', 'three', 'four'];
  /*  移除所有不满足条件的元素，此为Dart的一种速写语法
        numbersB.retainWhere((item) => item.length == 3);   */
  numbersB.retainWhere((item) {
    return item.length == 3;
  });
  print(numbersB);
  // -> [one, two]
}

/// 按顺序迭代列表
void initList_07 () {
  // List<String> names = ["Alice", "Daphne", "Elizabeth", "Joanna"];
  var names = <String>['Alice', 'Daphne', 'Elizabeth', 'Joanna'];
  names.forEach((name){
    // print(name);
  });
}

/// 各种查询输出方法
void initList_08 () {
  print('\x1B[102m  各种查询输出方法  \x1B[0m');
  var names = <String>['Alice', 'Daphne', 'Elizabeth', 'Joanna'];

  // 列表中是否包含指定元素
  print(names.contains('Fallon'));
  // -> false

  // 返回列表中的第几个元素
  print(names.elementAt(2));
  // -> Elizabeth

  // 返回列表中第一个匹配元素的下标
  print(names.indexOf('Callie'));
  // -> -1

  // 返回列表中最后一个匹配元素的下标
  print(names.lastIndexOf('Callie'));
  // -> -1

  var colors = <String>['red', 'green', 'blue', 'orange', 'pink'];
  // 返回从开始下标（包括）到结束下标（不包括）元素的列表
  print(colors.sublist(1, 3));
  // -> [green, blue]

  // 返回从开始下标（包括）到最后一个元素的列表
  print(colors.sublist(1));
  // -> [green, blue, orange, pink]
}

/// 对列表元素做一些改动
void initList_09 () {
  print('\x1B[102m  对列表元素做一些改动  \x1B[0m');
  var listA = <String>['a', 'b', 'c'];
  // 从第几个元素开始覆盖原列表
  listA.setAll(1, ['bee', 'sea']);
  print(listA);
  // -> [a, bee, sea]

  var listB = <int>[1, 2, 3, 4, 5];
  // 对列表进行随机排序
  listB.shuffle();
  print(listB);
  // -> [2, 3, 5, 4, 1]

  var listC = <int>[1, 2, 3, 4, 5];
  // 对列表进行顺序排序
  listC.sort();
  print(listC);
  // -> [1, 2, 3, 4, 5]
}
void main () {
  initList_01();
  initList_02();
  initList_03();
  initList_04();
  initList_05();
  initList_06();
  initList_07();
  initList_08();
  initList_09();
}
